package com.pan.demo.utils;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class DemoDataTool {

    private HashMap<Class, Method> typeMethodMap;

    {
        typeMethodMap = new HashMap<>();
        try {
            typeMethodMap.put(String.class,DemoDataTool.class.getMethod("randName"));
            typeMethodMap.put(int.class,DemoDataTool.class.getMethod("randAge") );
            typeMethodMap.put(Date.class,DemoDataTool.class.getMethod("randDate"));
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }

    public int randAge(){
        return (int) (Math.random()*100);
    }
    public Date randDate(){
        return new Date((long) (Math.random()*System.currentTimeMillis()));
    }

    public String randStr(){
        String ch = "qwertyuiopasdfghjklzxcvbnmQERTYUIOPADFGHJKLZXCVBNM";
        int len = 6;
        char result[] = new char[len];
        for (int i = 0; i < len; i++) {
            result[i] = ch.charAt((int) (Math.random()*ch.length()));
        }
        return new String(result);
    }


    private static String[] a;
    private static String b;
    static {
        a = new String[]{"a","e","i","o","u","ao","ou","ui","ei","ie","iao","an","on","en","in","ang","ong","eng","ing"};
        b = "QWRTYPSDFGHJKLZXCVBNM";
    }

    public String randName(){
        String name = "";
        for (int i = 0; i < 2; i++) {
            name += b.charAt((int) (Math.random()*b.length())) +a[(int) (Math.random()*a.length)];
        }
        return name;
    }


    public <T> List<T> newMockData(Class<T> clazz,int count) throws Exception {
        Constructor<T> constructor = clazz.getConstructor();
        Field[] declaredFields = clazz.getDeclaredFields();

        List<Field> fieldList = Arrays.stream(declaredFields)
                .filter(f -> typeMethodMap.containsKey(f.getType()))
                .collect(Collectors.toList());

        List<T> li = new LinkedList<>();
        for (int i = 0; i < count; i++) {
            T t = constructor.newInstance();
            fieldList.forEach(f->{
                f.setAccessible(true);
                Method method = typeMethodMap.get(f.getType());
                try {
                    f.set(t,method.invoke(this));
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                } catch (InvocationTargetException e) {
                    throw new RuntimeException(e);
                }
            });
            li.add(t);
        }
        return li;
    }
}
